package com.amumu.drama.common.modules.service.impl.payment;

import cn.hutool.core.util.StrUtil;
import com.amumu.drama.common.constant.PayProviderEnum;
import com.amumu.drama.common.constant.PayTypeEnum;
import com.amumu.drama.common.constant.SourceTypeEnum;
import com.amumu.drama.common.exception.Asserts;
import com.amumu.drama.common.modules.service.impl.payment.handler.PaymentHandler;
import com.amumu.drama.model.OmsOrder;
import com.beust.jcommander.internal.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@Slf4j
public class PaymentFactory implements ApplicationContextAware {

    private static Map<String, PaymentHandler> PAYMENT_MAP = Maps.newHashMap();

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        PAYMENT_MAP.clear();
        Map<String, PaymentHandler> paymentHandlerMap = applicationContext.getBeansOfType(PaymentHandler.class);
        paymentHandlerMap.forEach((k, v) -> {
            for (String type : v.type()) {
                PAYMENT_MAP.put(type, v);
            }
        });
    }

    public PaymentHandler getPaymentHandlerByOrder(OmsOrder order) {
        PayTypeEnum payTypeEnum = PayTypeEnum.getByKey(order.getPayType());
        PayProviderEnum payProviderEnum = PayProviderEnum.getByCode(order.getPayProvider());
        SourceTypeEnum sourceTypeEnum = SourceTypeEnum.getByCode(order.getSourceType());
        return getPaymentHandler(payTypeEnum, payProviderEnum, sourceTypeEnum);
    }

    public PaymentHandler getPaymentHandler(PayTypeEnum payTypeEnum, PayProviderEnum payProviderEnum, SourceTypeEnum sourceTypeEnum) {
        if (payProviderEnum == null || payTypeEnum == null || sourceTypeEnum == null) {
            log.error("未找到对应的支付bean,payProviderEnum:{},payTypeEnum:{},sourceTypeEnum:{}", payProviderEnum, payProviderEnum, sourceTypeEnum);
            Asserts.fail("未找到对应的支付bean");
        }
        return getPaymentHandler(getPayHandlerType(payTypeEnum, payProviderEnum, sourceTypeEnum));
    }

    public PaymentHandler getPaymentHandler(String payHandlerType) {
        PaymentHandler paymentHandler = PAYMENT_MAP.get(payHandlerType);
        if (paymentHandler == null) {
            log.error("未找到对应的支付bean,payHandlerType:{}", payHandlerType);
            Asserts.fail("未找到对应的支付bean");
        }
        return paymentHandler;
    }

    public static String getPayHandlerType(PayTypeEnum payTypeEnum, PayProviderEnum payProviderEnum, SourceTypeEnum sourceTypeEnum) {
        return StrUtil.join("_", payTypeEnum.getType(), payProviderEnum.getType(), sourceTypeEnum.getType());
    }

    public static String getPayHandlerType(OmsOrder order) {
        PayTypeEnum payTypeEnum = PayTypeEnum.getByKey(order.getPayType());
        PayProviderEnum payProviderEnum = PayProviderEnum.getByCode(order.getPayProvider());
        SourceTypeEnum sourceTypeEnum = SourceTypeEnum.getByCode(order.getSourceType());
        return getPayHandlerType(payTypeEnum, payProviderEnum, sourceTypeEnum);
    }
}
